package com.ruoyi.web.controller;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.business.PublishGoods;
import com.ruoyi.business.ao.PublishGoodsBuyByAdminAO;
import com.ruoyi.business.ao.PublishGoodsEditAO;
import com.ruoyi.business.bo.PublishGoodsBuyByAdminBO;
import com.ruoyi.business.bo.PublishGoodsBuyByUserBO;
import com.ruoyi.business.enums.PublishGoodsStatusEnum;
import com.ruoyi.business.enums.StatusEnum;
import com.ruoyi.business.enums.VipEnum;
import com.ruoyi.business.qo.PublishGoodsQO;
import com.ruoyi.business.service.AdminService;
import com.ruoyi.business.service.PublishGoodsService;
import com.ruoyi.business.vo.PublishGoodsListVO;
import com.ruoyi.business.vo.PublishGoodsSttaticticsVO;
import com.ruoyi.business.vo.PublishGoodsVO;
import com.ruoyi.common.common.CommonEnum;
import com.ruoyi.common.common.ResultBody;
import com.ruoyi.common.exception.BizException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.UUID;

/**
 * @title: CustomerController
 * @copyright: copyright (c) 2021
 * @author: jiangguanjun
 * @date: 2023/1/29 14:56
 * @firstReview:
 * @lastReview:
 * @desc: 访问相关
 */
@Api(value = "PublishGoodsController", tags = "发布采购单相关")
@RestController
@Slf4j
@RequestMapping("/publishGoods")
public class PublishGoodsController {
    @Autowired
    private PublishGoodsService publishGoodsService;

    @Value("${file.basepath}")
    private String basePath  ;

    @Autowired
    private AdminService adminService ;

    @CrossOrigin
    @PostMapping("/add")
    @ApiOperation(value = "发布采购单，address、phone、name、pPrice、pBuyNum、productName、cId 必填，页面：发布采购单")
    public ResultBody add(@RequestBody PublishGoods publishGoods){
        log.info("publishGoods:::{}",publishGoods);
        CommonEnum errorMessage = checkParam(publishGoods);
        if(errorMessage != null){
            log.error(errorMessage.getResultMsg());
            return ResultBody.error(errorMessage) ;
        }

        Long userId = SecurityUtils.getUserId() ;
        publishGoods.setaId(userId);

        int res = publishGoodsService.save(publishGoods);
        if(res>0){
            return ResultBody.success() ;
        }


        return ResultBody.error(CommonEnum.PUBLISH_ADD_ERROR) ;
    }

    @CrossOrigin
    @GetMapping("/changeStatus")
    @ApiOperation(value = "变更状态  页面：采购询价-变更状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "发布采购单的id", dataType = "Integer"),
            @ApiImplicitParam(name = "status", value = "状态，0：启用，1：禁用", dataType = "Integer")
    })
    public ResultBody changeStatus( @RequestParam(value = "status") Integer status,@RequestParam(value="id")Integer id){
        log.info("status:::{},id::::{}",status,id);
        if(!PublishGoodsStatusEnum.checkExist(status)){
            throw new BizException(CommonEnum.PUBLISH_STATUS_ERROR) ;
        }

        int res = publishGoodsService.changeStatus(status,id);
        if(res>0){
            return ResultBody.success() ;
        }
        return ResultBody.error(CommonEnum.PUBLISH_ADD_ERROR) ;
    }


    @CrossOrigin
    @PostMapping("/edit")
    @ApiOperation(value = "修改信息 页面：采购询价-修改")
    public ResultBody edit(@RequestBody PublishGoodsEditAO publishGoodsEditAO){
        log.info("publishGoodsEditAO:::::{}",publishGoodsEditAO);

        // 校验是否存在
        PublishGoods publishGoods = publishGoodsService.findById(publishGoodsEditAO.getId()) ;
        if(publishGoods == null){
            return ResultBody.error(CommonEnum.PUBLISH_NOT_EXIST_ERROR);
        }
        if(StatusEnum.FORBIDDEN.getCode()==publishGoods.getStatus().intValue()){
            return ResultBody.error(CommonEnum.PUBLISH_FORBIDDEN_ERROR);
        }
        //校验修改的个数不能小于当前已经购买过的个数
        if(publishGoodsEditAO.getpBuyNum() != null && publishGoodsEditAO.getpBuyNum()<publishGoods.getFinalBuyNum() ){
            return ResultBody.error(CommonEnum.PUBLISH_MUST_LARGE_ERROR);
        }

        // 校验发布的管理员和编辑的管理员是否为同一个
        Long userId = SecurityUtils.getUserId() ;
        if(!userId.equals(publishGoods.getaId())){
            return ResultBody.error(CommonEnum.PUBLISH_MUST_ONE_ERROR);
        }

        return publishGoodsService.edit(publishGoodsEditAO);
    }



    @CrossOrigin
    @PostMapping("/buyByAdmin")
    @ApiOperation(value = "管理员购买，页面：采购询价-买一次")
    public ResultBody buyByAdmin(@RequestBody PublishGoodsBuyByAdminAO publishGoodsBuyByAdminAO){
        log.info("publishGoodsBuyByAdminAO:::::{}",publishGoodsBuyByAdminAO);

        // 校验是否存在
        PublishGoods publishGoods = publishGoodsService.findById(publishGoodsBuyByAdminAO.getId()) ;
        if(publishGoods == null){
            return ResultBody.error(CommonEnum.PUBLISH_NOT_EXIST_ERROR);
        }
        if(StatusEnum.FORBIDDEN.getCode()==publishGoods.getStatus().intValue()){
            return ResultBody.error(CommonEnum.PUBLISH_FORBIDDEN_ERROR);
        }
        // 校验发布的管理员和编辑的管理员是否为同一个
        Long userId = SecurityUtils.getUserId() ;
        if(!userId.equals(publishGoods.getaId())){
            return ResultBody.error(CommonEnum.PUBLISH_MUST_ONE_ERROR);
        }
        //校验修改的个数不能小于当前已经购买过的个数
        if(publishGoodsBuyByAdminAO.getBuyNums() > publishGoods.getpBuyNum().intValue()-publishGoods.getFinalBuyNum()){
            return ResultBody.error(CommonEnum.PUBLISH_MUST_OVER_NUM_ERROR);
        }

        PublishGoodsBuyByAdminBO publishGoodsBuyByAdminBO = new PublishGoodsBuyByAdminBO() ;
        publishGoodsBuyByAdminBO.setId(publishGoodsBuyByAdminAO.getId());
        // 加上本次购买一共购买数量
        Integer buyAllNum = publishGoodsBuyByAdminAO.getBuyNums() + publishGoods.getFinalBuyNum() ;
        publishGoodsBuyByAdminBO.setFinalBuyNum(buyAllNum);
        publishGoodsBuyByAdminBO.setpBuy( publishGoods.getpBuyNum().intValue()-buyAllNum==0);
        publishGoodsBuyByAdminBO.setBuyNums(publishGoodsBuyByAdminAO.getBuyNums());
        return publishGoodsService.buyByAdmin(publishGoodsBuyByAdminBO);
    }

    @CrossOrigin
    @PostMapping("/buyAllByAdmin")
    @ApiOperation(value = "管理员买断，买掉剩余的所有未购买的，页面：采购询价-买断")
    public ResultBody buyAllByAdmin(@RequestBody JSONObject jsonObject){
        Integer id = jsonObject.getInteger("id") ;
        log.info("id:::::{}",id);

        // 校验是否存在
        PublishGoods publishGoods = publishGoodsService.findById(id) ;
        if(publishGoods == null){
            return ResultBody.error(CommonEnum.PUBLISH_NOT_EXIST_ERROR);
        }
        // 校验发布的管理员和编辑的管理员是否为同一个
        Long userId = SecurityUtils.getUserId() ;
        if(!userId.equals(publishGoods.getaId())){
            return ResultBody.error(CommonEnum.PUBLISH_MUST_ONE_ERROR);
        }

        // 管理员需要购买的数量
        int needBuyNum = publishGoods.getpBuyNum()-publishGoods.getFinalBuyNum() ;
        if(needBuyNum == 0){
            log.info("购买完毕");
            return ResultBody.error(CommonEnum.PUBLISH_BUY_FINAL_ERROR) ;
        }

        PublishGoodsBuyByAdminBO publishGoodsBuyByAdminBO = new PublishGoodsBuyByAdminBO() ;
        publishGoodsBuyByAdminBO.setId(id);
        // 加上本次购买一共购买数量
        publishGoodsBuyByAdminBO.setFinalBuyNum(publishGoods.getpBuyNum());
        publishGoodsBuyByAdminBO.setpBuy( true);
        publishGoodsBuyByAdminBO.setBuyNums(publishGoods.getpBuyNum()-publishGoods.getFinalBuyNum());
        return publishGoodsService.buyByAdmin(publishGoodsBuyByAdminBO);
    }



    @CrossOrigin
    @PostMapping("/list")
    @ApiOperation(value = "采购列表，页面：采购询价列表")
    public ResultBody<IPage<PublishGoodsListVO>> list(@RequestBody PublishGoodsQO publishGoodsQO){
        log.info("publishGoodsQO:::{}",publishGoodsQO);

        return publishGoodsService.list(publishGoodsQO);
    }

    @CrossOrigin
    @GetMapping("/pushVip")
    @ApiOperation(value = "推送采购信息给VIP用户，页面：VIP推送")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "采购信息id", dataType = "Integer")
    })
    public ResultBody pushVip(@RequestParam Integer id){
        log.info("id:::{}",id);

        return publishGoodsService.pushVip(id, VipEnum.VIP);
    }

    @CrossOrigin
    @GetMapping("/pushNomal")
    @ApiOperation(value = "推送采购信息给普通用户，页面：VIP推送")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "采购信息id", dataType = "Integer")
    })
    public ResultBody pushNomal(@RequestParam Integer id){
        log.info("id:::{}",id);

        return publishGoodsService.pushVip(id,VipEnum.NO_VIP);
    }

    @CrossOrigin
    @GetMapping("/staticticsList")
    @ApiOperation(value = "消费统计列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cId", value = "品类id", dataType = "Integer"),
            @ApiImplicitParam(name = "adminId", value = "管理员id", dataType = "Integer"),
            @ApiImplicitParam(name = "createStartTime", value = "开始时间时间戳", dataType = "Long"),
            @ApiImplicitParam(name = "createEndTime", value = "结束时间时间戳", dataType = "Long")
    })
    public ResultBody<PublishGoodsSttaticticsVO> staticticsList(@RequestParam(value = "cId" ,required = false)Integer cId,
                                                                @RequestParam(value = "adminId" ,required = false)Integer adminId,
                                                                @RequestParam(value = "createStartTime" ,required = false)Long createStartTime,
                                                                @RequestParam(value = "createEndTime" ,required = false)Long createEndTime){
        log.info("cId:::{};adminId:::{};createStartTime:::{};createEndTime:::{}",cId,adminId,createStartTime,createEndTime);

        return publishGoodsService.staticticsList(cId,adminId,createStartTime,createEndTime);
    }

    /**
     * @author jiangguanjun
     * @date 2023/2/8 17:10
     * @param
     * @return
     * @desc 文件上传
     */
    @CrossOrigin
    @ApiOperation(value = "文件上传")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "文件", dataType = "File")
    })
    @PostMapping(value = "/fileUpload")
    public ResultBody fileUpload(@RequestPart(name = "file", required = false) MultipartFile file) {

        if (file == null ) {
            log.error(CommonEnum.PUBLISH_FILL_EMPTY_ERROR.getResultMsg());
            return ResultBody.error(CommonEnum.PUBLISH_FILL_EMPTY_ERROR);
        }

        String originalName = file.getOriginalFilename() ;
        String suffix = originalName.substring(originalName.lastIndexOf(".")) ;
        String fileName = UUID.randomUUID()+suffix ;
        File dir = new File(basePath) ;
        if(!dir.exists()){
            dir.mkdir() ;
        }

        String fullFileName = basePath+fileName ;
        log.info("上传图片地址fullFileName：：{}",fullFileName);
        try {
            file.transferTo(new File(fullFileName));
        } catch (IOException e) {
            e.printStackTrace();
            log.error(CommonEnum.PUBLISH_FILL_UPLOAD_ERROR.getResultMsg());
            return ResultBody.error(CommonEnum.PUBLISH_FILL_UPLOAD_ERROR) ;
        }

        return ResultBody.success(fileName) ;
    }

    /**
     * @author jiangguanjun
     * @date 2023/2/8 17:10
     * @param
     * @return
     * @desc 文件下载
     */
    @CrossOrigin
    @ApiOperation(value = "文件下载")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fileName", value = "文件全路径", dataType = "String")
    })
    @GetMapping(value = "/fileDownload")
    public void fileDownload(@RequestParam(value = "fileName") String fileName, HttpServletResponse response) {

        response.reset();
        response.setContentType("application/octet-stream;charset=utf-8");
        response.setHeader(
                "Content-disposition",
                "attachment; filename="+fileName);
        String fullFileName = basePath+fileName ;
        log.info("下载图片地址：fullFileName：{}",fullFileName);
        try(

                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fullFileName));
                // 输出流
                BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
        ){
            byte[] buff = new byte[1024];
            int len = 0;
            while ((len = bis.read(buff)) > 0) {
                bos.write(buff, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * @author jiangguanjun
     * @date 2023/2/8 17:10
     * @param
     * @return
     * @desc 文件下载
     */
    @CrossOrigin
    @ApiOperation(value = "用户公众号端 通过采购单id 获取采购单详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "采购单id", dataType = "Integer")
    })
    @PostMapping(value = "/detailByUserAndId")
    public ResultBody<PublishGoodsVO> detailByUserAndId(@RequestBody JSONObject jsonObject) {
        Integer id = jsonObject.getInteger("id") ;
        Long userId = SecurityUtils.getUserId() ;

        PublishGoodsVO publishGoodsVO = publishGoodsService.findDetailByIdAndUserId(id,userId) ;

        return ResultBody.success(publishGoodsVO) ;
    }

    /**
     * @author jiangguanjun
     * @date 2023/2/8 17:10
     * @param
     * @return
     * @desc 文件下载
     */
    @CrossOrigin
    @ApiOperation(value = "用户公众号端 循环获取购买状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "采购单id", dataType = "Integer")
    })
    @PostMapping(value = "/getByStatusById")
    public ResultBody<PublishGoodsVO> getByStatusById(@RequestBody JSONObject jsonObject) {

        Integer id = jsonObject.getInteger("id") ;
        PublishGoodsVO publishGoodsVO = publishGoodsService.getByStatusById(id) ;

        return ResultBody.success(publishGoodsVO) ;
    }

    /**
     * @author jiangguanjun
     * @date 2023/10/5 17:10
     * @param
     * @return
     * @desc 管理端查看详情
     */
    @CrossOrigin
    @ApiOperation(value = "管理端 通过采购单id 获取采购单详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "采购单id", dataType = "Integer")
    })
    @GetMapping(value = "/detailById")
    public ResultBody<PublishGoodsVO> detailById(@RequestParam(value = "id") Integer id) {

        PublishGoodsVO publishGoodsVO = publishGoodsService.findDetailById(id) ;

        return ResultBody.success(publishGoodsVO) ;
    }


    @CrossOrigin
    @PostMapping("/buyByUser")
    @ApiOperation(value = "用户购买 ")
    public ResultBody buyByUser(@RequestBody PublishGoodsBuyByAdminAO publishGoodsBuyByAdminAO){
        log.info("publishGoodsBuyByAdminAO:::::{}",publishGoodsBuyByAdminAO);

        // 校验是否存在
        PublishGoods publishGoods = publishGoodsService.findById(publishGoodsBuyByAdminAO.getId()) ;
        if(publishGoods == null){
            return ResultBody.error(CommonEnum.PUBLISH_NOT_EXIST_ERROR);
        }
        if(StatusEnum.FORBIDDEN.getCode()==publishGoods.getStatus().intValue()){
            return ResultBody.error(CommonEnum.PUBLISH_FORBIDDEN_ERROR);
        }

        //校验修改的个数不能小于当前已经购买过的个数
        if(publishGoodsBuyByAdminAO.getBuyNums() > publishGoods.getpBuyNum().intValue()-publishGoods.getFinalBuyNum()){
            return ResultBody.error(CommonEnum.PUBLISH_MUST_OVER_NUM_ERROR);
        }

        PublishGoodsBuyByUserBO publishGoodsBuyByUserBO = new PublishGoodsBuyByUserBO() ;
        publishGoodsBuyByUserBO.setId(publishGoodsBuyByAdminAO.getId());
        // TODO 扣除账户余额
        // 加上本次购买一共购买数量
        Long userId = SecurityUtils.getUserId() ;


        publishGoodsBuyByUserBO.setUserId(userId);
        Integer buyAllNum = publishGoodsBuyByAdminAO.getBuyNums() + publishGoods.getFinalBuyNum() ;
        publishGoodsBuyByUserBO.setFinalBuyNum(buyAllNum);
        publishGoodsBuyByUserBO.setpBuy( publishGoods.getpBuyNum().intValue()-buyAllNum==0);
        publishGoodsBuyByUserBO.setBuyNums(publishGoodsBuyByAdminAO.getBuyNums());
        return publishGoodsService.buyByUser(publishGoodsBuyByUserBO);
    }

    private CommonEnum checkParam(PublishGoods publishGoods) {
        if(StringUtils.isBlank(publishGoods.getAddress())){
            return CommonEnum.PUBLISH_ADDRESS_EMPTY ;
        }
        if(StringUtils.isBlank(publishGoods.getName())){
            return CommonEnum.PUBLISH_NAME_EMPTY ;
        }
        if(StringUtils.isBlank(publishGoods.getPhone())) {
            return CommonEnum.PUBLISH_PHONE_EMPTY;
        }
        if(publishGoods.getpPrice() == null){
            return CommonEnum.PUBLISH_PRICE_EMPTY;
        }
        if(publishGoods.getpBuyNum() == null){
            return CommonEnum.PUBLISH_NUM_EMPTY;
        }
        if(StringUtils.isBlank(publishGoods.getProductName())){
            return CommonEnum.PUBLISH_PRODUCT_NAME_EMPTY;
        }
        if(publishGoods.getcId() == null){
            return CommonEnum.PUBLISH_CATEGORYE_EMPTY;
        }

        return null ;
    }


}
